﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Input;
using CLEXA.ClientTools.Collections;
using CLEXA.DataContracts;
using CLEXA.SurfaceClient.Functions;

namespace CLEXA.SurfaceClient.ViewModel
{
    public class HomeVM : VMBase
    {
        private readonly IHome facade;
        private readonly ListBinding<int, DatabaseData, DatabaseReadVM> databases;
        private DatabaseReadVM selectedDatabase;
        private readonly RelayCommand logout;
        private readonly RelayCommand newDatabase;
        private readonly RelayCommand goDatabase;
        private readonly RelayCommand editDatabase;
        private readonly RelayCommand deleteDatabase;

        public IEnumerable<DatabaseReadVM> Databases
        {
            get { return databases.ObservableCollection; }
        }

        public DatabaseReadVM SelectedDatabase
        {
            get { return selectedDatabase; }
            set
            {
                if (selectedDatabase != value)
                {
                    selectedDatabase = value;
                    RaisePropertyChanged("SelectedDatabase");
                    newDatabase.RaiseCanExecuteChanged();
                    goDatabase.RaiseCanExecuteChanged();
                    editDatabase.RaiseCanExecuteChanged();
                    deleteDatabase.RaiseCanExecuteChanged();
                }
            }
        }

        public ICommand Logout
        {
            get { return logout; }
        }

        public RelayCommand NewDatabase
        {
            get { return newDatabase; }
        }

        public ICommand GoDatabase
        {
            get { return goDatabase; }
        }

        public ICommand EditDatabase
        {
            get { return editDatabase; }
        }

        public ICommand DeleteDatabase
        {
            get { return deleteDatabase; }
        } 

        public HomeVM(IHome facade)
        {
            this.facade = facade;
            this.databases = new ListBinding<int, DatabaseData, DatabaseReadVM>(facade.Databases, ToDatabaseReadVM, DatabaseReadVM.IdentityComparer);
            this.logout = new RelayCommand(DoLogout);
            this.newDatabase = new RelayCommand(DoNew);
            this.goDatabase = new RelayCommand(DoGo, CanGo);
            this.editDatabase = new RelayCommand(DoEdit, CanEdit);
            this.deleteDatabase = new RelayCommand(DoDelete, CanDelete);
        }

        public static DatabaseReadVM ToDatabaseReadVM(DatabaseData database)
        {
            string databaseName;
            try
            {
                databaseName = Helper.GetDatabaseNameFromConnectionString(database.ConnectionString);
            }
            catch
            {
                databaseName = "<unkown>";
            }
            string serverName;
            try
            {
                serverName = Helper.GetServerNameFromConnectionString(database.ConnectionString);
            }
            catch
            {
                serverName = "<unkown>";
            }

            return new DatabaseReadVM(database.DatabaseId, database.UserId, serverName, databaseName, database.ConnectionString);
        }

        private void DoLogout()
        {
            facade.GoToLogin();
        }

        private void DoNew()
        {
            facade.ShowNewDatabase();
        }

        private void DoGo()
        {
            facade.GoToSchema(new DatabaseData(selectedDatabase.DatabaseId, selectedDatabase.UserId, selectedDatabase.ConnectionString));
        }

        private bool CanGo()
        {
            return selectedDatabase != null;
        }

        private void DoEdit()
        {
            facade.ShowEditDatabase(selectedDatabase.DatabaseId);
        }

        private bool CanEdit()
        {
            return selectedDatabase != null;
        }

        private void DoDelete()
        {
            facade.ShowDeleteDatabase(selectedDatabase.DatabaseId);
            SelectedDatabase = null;
        }

        private bool CanDelete()
        {
            return selectedDatabase != null;
        }
    }
}
